package cn.wolfocde.luowowo.service.impl;

import cn.wolfcode.luowowo.query.SearchQueryObject;
import cn.wolfcode.luowowo.search.service.IStrategyTemplateSearchService;
import cn.wolfcode.luowowo.search.template.StrategyTemplate;
import cn.wolfcode.luowowo.vo.StatisVo;
import cn.wolfocde.luowowo.repository.StrategyTemplateRepository;
import com.alibaba.dubbo.config.annotation.Service;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.bucket.composite.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.util.*;

/**
 * Created by LENOVO on 2019/8/17.
 */

@Service
public class StrategyTemplateSearchService implements IStrategyTemplateSearchService {

    //es 依然使用spring-data-jpa

    //repository 封装了template
    //template 封装了 client

    @Autowired
    private StrategyTemplateRepository repository;
    @Autowired
    private ElasticsearchTemplate template;
    @Autowired
    private TransportClient client;  //java操作es的第三方客户端


    public void saveOrUpdate(StrategyTemplate template) {
        repository.save(template);
    }


    //攻略主题的获取
    @Override
    public List<Map<String, Object>> getThemeCommend() {
        List<Map<String, Object>> data= new ArrayList<>();
        //------------------查询所有的主题--------------

        //拼接查询聚合字段的信息
        List<CompositeValuesSourceBuilder<?>> sources=new ArrayList<>();

        //分组查询中 id这个key
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");
        idSource.missingBucket(true);//忽略不满足的条件
        idSource.field("themeId");
        sources.add(idSource);


        //分组查询中 id为这个那么
        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");
        nameSource.missingBucket(true);//忽略不满足的条件
        nameSource.field("themeName");
        sources.add(nameSource);



        //参数1：分组查询结果名称 参数2，分组查询字段匹配集合对象集合
        CompositeAggregationBuilder aggBuilder = new CompositeAggregationBuilder("themeGroup", sources);


        //发起查询请求操作
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withIndices(StrategyTemplate.INDEX_NAME);//查询的索引
        builder.withTypes(StrategyTemplate.TYPE_NAME); //查询的类型
        builder.addAggregation(aggBuilder);   //集合查询构建模块



        //聚合查询的结果
        AggregatedPage<StrategyTemplate> page= (AggregatedPage<StrategyTemplate>) repository.search(builder.build());

        //分组查询结果对象:backets 封装对象
        InternalComposite aggregation = page.getAggregations().get("themeGroup");

        List<StatisVo> themes=new ArrayList<>();
        //遍历buckets
        for(CompositeAggregation.Bucket bucket:aggregation.getBuckets()){
            Map<String,Object> key =bucket.getKey();
            StatisVo vo = new StatisVo();
            vo.setId(Long.parseLong(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(bucket.getDocCount());
                themes.add(vo);
        }

        //第一完善：排序，theme集合中根据docCount,这里用倒序
        Collections.sort(themes, new Comparator<StatisVo>() {
            @Override
            public int compare(StatisVo o1, StatisVo o2) {
                return Integer.valueOf(o2.getCount()-o1.getCount()+"");
            }
        });
        //第二完善 :截取前面10个
        List<StatisVo> subThemes=null;
        if(themes.size() >10){
            subThemes=themes.subList(0,10);
        }else {
            subThemes=themes.subList(0,themes.size());
        }


        //----------遍历所有的主题查询该主题下所有的目的地
        for (StatisVo theme:subThemes){
            List<StatisVo> dests = this.getDestByThemeId(theme.getId());
            //左边注解vo  右边的目的地的集合
            Map<String,Object> map=new HashMap<>();
            map.put("theme",theme);
            map.put("dests",dests);
            data.add(map);
        }

        return data;
    }



    private List<StatisVo> getDestByThemeId(Long themeId){
        Iterable<StrategyTemplate> iterable = repository.search(QueryBuilders.termQuery("themeId", themeId));
        List<StatisVo> list=new ArrayList<>();
       /* Iterator<StrategyTemplate> iterator = iterable.iterator();
        while (iterator.hasNext()){
            StrategyTemplate st=iterator.next();
            StatisVo vo=new StatisVo();
            vo.setId(st.getDestId());
            vo.setName(st.getDestName());
            list.add(vo);
        }*/
        List<String> temp =new ArrayList<>();//防止已经存在的目的地地名名称

        iterable.forEach(st ->{
            //如果临时的list中不存在这个目的地名,执行添加操作
            if(!temp.contains(st.getDestName())){
                StatisVo vo = new StatisVo();
                vo.setId(st.getDestId());
                vo.setName(st.getDestName());
                list.add(vo);

                temp.add(st.getDestName());
            }
        });

        return list;
    }





    //根据不同维度封装查询
    private List<StatisVo>  statisGroup(String idField, String nameField, String groupName, BoolQueryBuilder query){
        //----------查询出所有维度数据-----------------------
        //拼接聚合查询字段信息
        List<CompositeValuesSourceBuilder<?>> sources = new ArrayList<>();

        //分组查询中: id这个key
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");
        idSource.missingBucket(true);  //忽略不满足条件bucket
        idSource.field(idField);
        sources.add(idSource);

        //分组查询中: id这个name
        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");
        nameSource.missingBucket(true);  //忽略不满足条件bucket
        nameSource.field(nameField);
        sources.add(nameSource);

        //参数1:分组查询结果名称   参数2:分组查询字段配置对象集合
        CompositeAggregationBuilder aggsBuilder = new CompositeAggregationBuilder(groupName, sources);


        //发起查询请求操作
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withIndices(StrategyTemplate.INDEX_NAME);  //查询的索引
        builder.withTypes(StrategyTemplate.TYPE_NAME);  //查询类型
        builder.addAggregation(aggsBuilder);  //聚合查询构建模块
        //builder.withPageable(PageRequest.of(0, 1));  //size = 0 因为pageable中的size不能为0, 只能使用1


        if(query != null){
            builder.withQuery(query);
        }
        //聚合查询结果
        AggregatedPage<StrategyTemplate> page = (AggregatedPage<StrategyTemplate>) repository.search(builder.build());
        //分组查询结果对象: buckets 封装对象
        InternalComposite aggregation = page.getAggregations().get(groupName);
        //结果封装
        List<StatisVo>  themes = new ArrayList<>();
        //遍历buckets
        for (CompositeAggregation.Bucket bucket : aggregation.getBuckets()) {

            Map<String, Object> key = bucket.getKey();

            if(key.get("id")== null || key.get("name") == null){
                continue;
            }
            StatisVo vo = new StatisVo();
            vo.setId(Long.parseLong(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(bucket.getDocCount());
            themes.add(vo);
        }

        //第一完善: 排序, themes集合中根据DocCount大小排序, 此处使用倒序
        Collections.sort(themes, new Comparator<StatisVo>() {
            //返回结果是int类型
            //正数:表示大于
            //负数:表示小于
            //0  :表示等于
            @Override
            public int compare(StatisVo o1, StatisVo o2) {
                return Integer.valueOf((o2.getCount() - o1.getCount()) + "");
            }
        });
        return themes;
    }




    @Override
    public List<StatisVo> queryConditionGroup(int type) {
        String idField="";
        String nameField="";
        BoolQueryBuilder query = null;
        if(type == SearchQueryObject.CONDITION_TYPE_ABROAD){
            idField = "countryId";
            nameField= "countryName";
            //如果按照国家操作时, 需要排除中国
            //QueryBuilders.termQuery("")
            query = QueryBuilders.boolQuery().mustNot(
                    QueryBuilders.termQuery("countryId", 1));
        }else if(type == SearchQueryObject.CONDITION_TYPE_UN_ABROAD){
            idField = "provinceId";
            nameField= "provinceName";
        }else if(type == SearchQueryObject.CONDITION_TYPE_THEME){
            idField = "themeId";
            nameField= "themeName";
        }




        return this.statisGroup(idField,nameField,"conditionGroup",query);


    }



    @Override
    public Page query(SearchQueryObject qo) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        if(qo.getType()==SearchQueryObject.CONDITION_TYPE_ABROAD){
                boolQuery.must(QueryBuilders.termQuery("countryId",qo.getTypeValue()));//国家的id
        }else if(qo.getType()==SearchQueryObject.CONDITION_TYPE_UN_ABROAD){
            boolQuery.must(QueryBuilders.termQuery("provinceId",qo.getTypeValue()));//zhon中国,省份
        }else if(qo.getType()==SearchQueryObject.CONDITION_TYPE_THEME){
            boolQuery.must(QueryBuilders.termQuery("themeId",qo.getTypeValue()));//主题来确定的
        }

        return repository.search(boolQuery,qo.getPageable());
    }

    @Override
    public List<StrategyTemplate> findByDestName(String name) {
            return repository.findByDestName(name);


    }


}
